package com.kelaite.procurement.service.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kelaite.procurement.dto.CompanyDTO;
import com.kelaite.procurement.dto.PipelineHeaderDTO;
import com.kelaite.procurement.dto.PipelineItemDTO;
import com.kelaite.procurement.entity.TCompany;
import com.kelaite.procurement.entity.TDemand;
import com.kelaite.procurement.entity.TPipelineItem;
import com.kelaite.procurement.exception.BusinessException;
import com.kelaite.procurement.repository.PipelineItemRepository;
import com.kelaite.procurement.service.PipelineItemService;
import com.kelaite.procurement.utils.ConvertUtil;

@Service
@Transactional
public class PipelineItemServiceImpl implements PipelineItemService {

	@Autowired
	private PipelineItemRepository pipelineItemRepository;

	@PersistenceContext
	private EntityManager em;

	@Override
	public TPipelineItem save(TPipelineItem persistence) {
		return this.pipelineItemRepository.save(persistence);
	}

	@Override
	public TPipelineItem getObject(Long id) {
		return this.pipelineItemRepository.findOne(id);
	}

	@Override
	public List<TPipelineItem> getAll() {
		return this.pipelineItemRepository.findAll();
	}

	@Override
	public void deleteByObject(TPipelineItem persistence) {
		this.pipelineItemRepository.delete(persistence);
	}

	@Override
	public void deleteByPrimaryKey(Long id) {
		this.pipelineItemRepository.delete(id);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<TPipelineItem> getByProperty(String property, Object value) {
		Session session = (org.hibernate.Session) em.getDelegate();
		Criteria criteria = session.createCriteria(TPipelineItem.class).add(
				Restrictions.eq(property, value));
		return criteria.list();
	}

	@Override
	public PipelineItemDTO getPipelineItemByHeaderId(Long pipelineId) {

		TPipelineItem dbPipelineItem = pipelineItemRepository
				.findByPipelineId(pipelineId);
		if (null == dbPipelineItem) {
			throw new BusinessException(String.format(
					"pipeline id %s not exsist.", pipelineId));
		}
		PipelineItemDTO itemDto = ConvertUtil.convertObj(dbPipelineItem,
				PipelineItemDTO.class);
		//
		itemDto.settPipelineHeader(ConvertUtil.convertObj(
				dbPipelineItem.gettPipelineHeader(), PipelineHeaderDTO.class));
		itemDto.seCompanyDTOId1(ConvertUtil.convertObj(
				dbPipelineItem.getCompanyId1(), CompanyDTO.class));
		itemDto.seCompanyDTOId2(ConvertUtil.convertObj(
				dbPipelineItem.getCompanyId2(), CompanyDTO.class));
		itemDto.seCompanyDTOId3(ConvertUtil.convertObj(
				dbPipelineItem.getCompanyId3(), CompanyDTO.class));
		return itemDto;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<TPipelineItem> findByCompany(TCompany[] companyObjects) {
		Session session = (org.hibernate.Session) em.getDelegate();
		Criteria pipelineItemcriteria = session.createCriteria(TPipelineItem.class);
		pipelineItemcriteria.addOrder(Order.desc("id"));
		Criteria pipelineHeaderCriteria = pipelineItemcriteria.createCriteria("tPipelineHeader");
		pipelineHeaderCriteria.add(Restrictions.in("tCompany", companyObjects));
		return pipelineItemcriteria.list();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<TPipelineItem> findByCompanyAndDemand(TCompany company, TDemand demand) {
		Session session = (org.hibernate.Session) em.getDelegate();
		Criteria pipelineItemcriteria = session.createCriteria(TPipelineItem.class);
		pipelineItemcriteria.addOrder(Order.desc("id"));
		Criteria pipelineHeaderCriteria = pipelineItemcriteria.createCriteria("tPipelineHeader");
		pipelineHeaderCriteria.add(Restrictions.eq("tCompany", company));  
		pipelineHeaderCriteria.add(Restrictions.eq("tDemand", demand));  
		return pipelineItemcriteria.list();
	}

}
